var _excluded = [
  'pathname',
  'base',
  'routes',
  'mode',
  'sensitive',
  'onClick',
  'renderMenuTitle',
  'IconComponents',
];
function _extends() {
  _extends = Object.assign
    ? Object.assign.bind()
    : function (target) {
        for (var i = 1; i < arguments.length; i++) {
          var source = arguments[i];
          for (var key in source) {
            if (Object.prototype.hasOwnProperty.call(source, key)) {
              target[key] = source[key];
            }
          }
        }
        return target;
      };
  return _extends.apply(this, arguments);
}
function _toConsumableArray(arr) {
  return (
    _arrayWithoutHoles(arr) ||
    _iterableToArray(arr) ||
    _unsupportedIterableToArray(arr) ||
    _nonIterableSpread()
  );
}
function _nonIterableSpread() {
  throw new TypeError(
    'Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.',
  );
}
function _iterableToArray(iter) {
  if (
    (typeof Symbol !== 'undefined' && iter[Symbol.iterator] != null) ||
    iter['@@iterator'] != null
  )
    return Array.from(iter);
}
function _arrayWithoutHoles(arr) {
  if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _slicedToArray(arr, i) {
  return (
    _arrayWithHoles(arr) ||
    _iterableToArrayLimit(arr, i) ||
    _unsupportedIterableToArray(arr, i) ||
    _nonIterableRest()
  );
}
function _nonIterableRest() {
  throw new TypeError(
    'Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.',
  );
}
function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === 'string') return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === 'Object' && o.constructor) n = o.constructor.name;
  if (n === 'Map' || n === 'Set') return Array.from(o);
  if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
    return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;
  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  return arr2;
}
function _iterableToArrayLimit(arr, i) {
  var _i =
    null == arr
      ? null
      : ('undefined' != typeof Symbol && arr[Symbol.iterator]) || arr['@@iterator'];
  if (null != _i) {
    var _s,
      _e,
      _x,
      _r,
      _arr = [],
      _n = !0,
      _d = !1;
    try {
      if (((_x = (_i = _i.call(arr)).next), 0 === i)) {
        if (Object(_i) !== _i) return;
        _n = !1;
      } else
        for (
          ;
          !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i);
          _n = !0
        );
    } catch (err) {
      (_d = !0), (_e = err);
    } finally {
      try {
        if (!_n && null != _i.return && ((_r = _i.return()), Object(_r) !== _r)) return;
      } finally {
        if (_d) throw _e;
      }
    }
    return _arr;
  }
}
function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr;
}
function _objectWithoutProperties(source, excluded) {
  if (source == null) return {};
  var target = _objectWithoutPropertiesLoose(source, excluded);
  var key, i;
  if (Object.getOwnPropertySymbols) {
    var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
    for (i = 0; i < sourceSymbolKeys.length; i++) {
      key = sourceSymbolKeys[i];
      if (excluded.indexOf(key) >= 0) continue;
      if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
      target[key] = source[key];
    }
  }
  return target;
}
function _objectWithoutPropertiesLoose(source, excluded) {
  if (source == null) return {};
  var target = {};
  var sourceKeys = Object.keys(source);
  var key, i;
  for (i = 0; i < sourceKeys.length; i++) {
    key = sourceKeys[i];
    if (excluded.indexOf(key) >= 0) continue;
    target[key] = source[key];
  }
  return target;
}
import AppstoreOutlined from '@ant-design/icons/AppstoreOutlined';
import { useRealtimeRef, useTree } from '@szzj/hooks';
import { Menu } from 'antd';
import 'antd/es/menu/style/index.js';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { Link, matchPath } from 'react-router-dom';
import './index.less';
/**
 * 菜单，由 Layout 或 props 保证 key 键
 * @param param0
 * @returns
 */
export default function Menus(_ref) {
  var _ref$pathname = _ref.pathname,
    pathname = _ref$pathname === void 0 ? '/' : _ref$pathname,
    base = _ref.base,
    routes = _ref.routes,
    _ref$mode = _ref.mode,
    mode = _ref$mode === void 0 ? 'inline' : _ref$mode,
    _ref$sensitive = _ref.sensitive,
    sensitive = _ref$sensitive === void 0 ? true : _ref$sensitive,
    _onClick = _ref.onClick,
    renderMenuTitle = _ref.renderMenuTitle,
    IconComponents = _ref.IconComponents,
    rest = _objectWithoutProperties(_ref, _excluded);
  /** 设置展开菜单的 key */
  var _useState = useState([]),
    _useState2 = _slicedToArray(_useState, 2),
    openKeys = _useState2[0],
    setOpenKeys = _useState2[1];
  /** 设置选中子菜单的 key */
  var _useState3 = useState([]),
    _useState4 = _slicedToArray(_useState3, 2),
    selectedKeys = _useState4[0],
    setSelectedKeys = _useState4[1];
  var tree = useTree(routes, {
    uniqueKey: 'key',
    childrenKey: 'routes',
  });
  var treeRef = useRealtimeRef(tree);

  /** 基础路径下的路由节点 */
  var baseChildRoutes = useMemo(
    function () {
      if (base && base !== '/') {
        var _baseRoute$routes;
        var baseRoute = treeRef.current.findNode(base);
        if (!baseRoute) return routes;
        return baseRoute !== null && baseRoute !== void 0 && baseRoute.title
          ? [baseRoute]
          : (_baseRoute$routes =
              baseRoute === null || baseRoute === void 0 ? void 0 : baseRoute.routes) !== null &&
            _baseRoute$routes !== void 0
          ? _baseRoute$routes
          : [];
      }
      return routes;
    },
    [base, routes],
  );

  /**
   * 设置默认展开的菜单
   */
  useEffect(
    function () {
      var defaultOpenedRoutes = treeRef.current.filter(baseChildRoutes, function (route) {
        return !!route.menu && !!route.defaultOpened;
      });
      var defaultOpenedRoutesArr = treeRef.current.toArray(defaultOpenedRoutes);
      setOpenKeys(
        defaultOpenedRoutesArr.map(function (route) {
          return route.key;
        }),
      );
    },
    [baseChildRoutes],
  );

  /**
   * 以下三种方式会引起 openKeys, selectedKeys 变更：
   * 1，浏览器地址栏变更访问；
   * 2，点击菜单跳转；
   * 3，点击面包屑跳转；
   */
  var openKeysRef = useRealtimeRef(openKeys);
  var sensitiveRef = useRealtimeRef(sensitive);
  useEffect(
    function () {
      var baseChildRoutesArr = treeRef.current.toArray(baseChildRoutes);
      var matchedRoutes = treeRef.current.filter(baseChildRoutesArr, function (route) {
        return (
          !!route.menu &&
          !!matchPath(
            {
              path: route.path,
            },
            pathname,
          )
        );
      });
      treeRef.current.forEach(matchedRoutes, function (route) {
        var _route$routes;
        if (
          (_route$routes = route.routes) !== null &&
          _route$routes !== void 0 &&
          _route$routes.length
        ) {
          if (!openKeysRef.current.includes(route.key)) {
            if (sensitiveRef.current) {
              setOpenKeys(function (keys) {
                return [].concat(_toConsumableArray(keys), [route.key]);
              });
            }
          }
        } else if (route.path.split('/').length === pathname.split('/').length) {
          if (!selectedKeys.includes(route.key)) {
            setSelectedKeys([route.key]);
          }
        }
      });
    },
    [baseChildRoutes, pathname],
  );
  var renderIcon = useCallback(
    function (route, level) {
      var defaultCustomIcon = IconComponents && IconComponents.default;
      var DefaultIcon = !level ? defaultCustomIcon || AppstoreOutlined : undefined;

      // 使用 route.Icon 缓存加载完的图标，避免多次加载
      var Icon = route.Icon || DefaultIcon;
      if (!route.Icon && route.icon) {
        if (IconComponents) {
          Icon = IconComponents[route.icon];
          route.Icon = Icon;
        } else {
          // @ts-ignore
          Icon = /*#__PURE__*/ React.lazy(function () {
            var result;
            try {
              result = require('@ant-design/icons/'.concat(route.icon, '.js'));
            } catch (err) {
              console.warn(
                'icon: '.concat(
                  route.icon,
                  ' is not available. @szzj/layout will use default icon.',
                ),
              );
              result = {
                default: DefaultIcon,
              };
            }
            return Promise.resolve(result);
          });
          route.Icon = Icon;
          route.lazy = true;
          return /*#__PURE__*/ React.createElement(
            'span',
            {
              className: 'anticon szzj-menu-icon',
            },
            /*#__PURE__*/ React.createElement(
              React.Suspense,
              {
                fallback: null,
              },
              /*#__PURE__*/ React.createElement(Icon, null),
            ),
          );
        }
      }
      if (route.lazy && Icon) {
        return /*#__PURE__*/ React.createElement(
          'span',
          {
            className: 'anticon szzj-menu-icon',
          },
          /*#__PURE__*/ React.createElement(
            React.Suspense,
            {
              fallback: null,
            },
            /*#__PURE__*/ React.createElement(Icon, null),
          ),
        );
      }

      // antd 机制，sider 折叠时，anticon 后的 span 宽度会被置为 0
      return Icon
        ? /*#__PURE__*/ React.createElement(
            'span',
            {
              className: 'anticon szzj-menu-icon',
            },
            Icon ? /*#__PURE__*/ React.createElement(Icon, null) : null,
          )
        : null;
    },
    [IconComponents],
  );
  var getItem = useCallback(
    function (route) {
      var _route$routes2;
      var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
      var icon = renderIcon(route, level);
      var title = renderMenuTitle ? renderMenuTitle(route, level) : route.title;
      if (
        (_route$routes2 = route.routes) !== null &&
        _route$routes2 !== void 0 &&
        _route$routes2.length
      ) {
        return {
          key: route.key,
          icon: icon,
          label: title,
          title: route.title,
          disabled: route.disabled,
          danger: route.danger,
          children: route.routes.map(function (childRoute) {
            return getItem(childRoute, level + 1);
          }),
        };
      } else {
        return {
          key: route.key,
          icon: icon,
          label:
            route.target || _onClick
              ? title
              : /*#__PURE__*/ React.createElement(
                  Link,
                  {
                    to: route.path,
                  },
                  title,
                ),
          title: route.title,
          disabled: route.disabled,
          danger: route.danger,
        };
      }
    },
    [renderIcon, _onClick, renderMenuTitle],
  );
  return /*#__PURE__*/ React.createElement(
    Menu,
    _extends(
      {
        mode: mode,
      },
      rest,
      {
        selectedKeys: selectedKeys,
        openKeys: openKeys,
        onOpenChange: setOpenKeys,
        items: baseChildRoutes
          .filter(function (route) {
            return !!route.menu;
          })
          .map(function (route) {
            return getItem(route, 0);
          }),
        onClick: function onClick(_ref2) {
          var key = _ref2.key;
          var route = treeRef.current.findNode(key);
          if (_onClick) _onClick(route);
          else if (route.target) window.location.href = route.target;
        },
      },
    ),
  );
}
